package com.opc.quarz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.opc.Common.MessageConstant;
import com.opc.Common.TransmittersMessage;
import com.opc.Config.CacheUtil;
import com.opc.Mapper.*;
import com.opc.Pojo.*;
import com.opc.Service.*;
import com.opc.properties.CarTypeProperties;
import com.opc.properties.FrequencyProperties;
import com.opc.properties.GunProperties;
import com.opc.properties.IpProperties;
import com.opc.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.ConnectException;
import java.net.Socket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@DisallowConcurrentExecution // 确保任务不会并发执行
//@Transactional
public class HeartBeatQuartz4 extends QuartzJobBean implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    // 1. 提取常量（提升可维护性）
    private static final String CACHE_KEY_4TIMES = "4times";
    private static final String ERROR_MESSAGE = "--数据库无数据--\n--未知车型--\n--车身号前缀未设置--";

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Autowired
    private IpProperties ipProperties;
    @Autowired
    //@Qualifier("jSerialCommIOService")
    private JSerialCommIOService jSerialCommIOService;
    @Autowired
    private GunProperties gunProperties;
    @Autowired
    private FrequencyProperties frequencyProperties;
    @Autowired
    private WeldingGunMapper weldingGunMapper;
    @Autowired
    private WeldingGunService weldingGunService;
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private ScrewService screwService;
    //    @Autowired
//    private TorqueStandardsService torqueStandardsService;
    @Autowired
    private TorqueStandardsMapper torqueStandardsMapper;
    @Autowired
    private CarMapper carMapper;
    @Autowired
    private CarService carService;
    @Autowired
    private CarStatusMapper carStatusMapper;
    //    @Autowired
//    private IPService IPService;
    @Autowired
    private ScrewTypeMapper screwTypeMapper;
    @Autowired
    private ScrewMapper screwMapper;

    @Autowired
    private CarTypeProperties carTypeProperties;

    private void reconnectwaitingtime(){
        try {
            // 使用TimeUnit替代Thread.sleep，语义更清晰
            TimeUnit.MILLISECONDS.sleep(frequencyProperties.getReconnectwaitingtime());
        } catch (InterruptedException e) {
            // 正确处理中断：恢复中断状态，便于上层感知
            Thread.currentThread().interrupt();
            // 中断时退出循环（根据业务需求决定是否退出）
//            break;
        }
    }
    @Override
//    @Async("asyncExecutor")
//    @Transactional(rollbackFor = Exception.class)
    public void executeInternal(JobExecutionContext context){
        //打印线程id
        log.info("控制器4的线程id:{}", Thread.currentThread().getId()+"名"+Thread.currentThread().getName());
        CacheUtil.putInCache("controller4", "0");
        int attempt = 1; // 初始化重试计数器
//        int test0 = 1;
//        int test = 1; // 消息只发一次消息提示
        String gun1Num = gunProperties.getGun1();
        String gun2Num = gunProperties.getGun2();
        String gun3Num = gunProperties.getGun3();
        String gun4Num = gunProperties.getGun4();//ReSelectParamgramNum
        String lastCarTypeString;
        while (true) {
            // 增加重试计数
            log.info("尝试第-{}-次连接cvi34", attempt);
            log.info("心跳任务执行....连接cvi34--{}:{}",ipProperties.getCvi34(),ipProperties.getPort4());
            attempt++;
            try (Socket socket = new Socket(ipProperties.getCvi34(),
                    ipProperties.getPort4())) {
                log.info("心跳4程序连接成功");
                // 获取输出流
                OutputStream out = socket.getOutputStream();
                // 发送第一条命令
                String firstCommand = TransmittersMessage.Start_Communication; // 第一条命令
                out.write(firstCommand.getBytes());
                out.flush(); // 确保数据已经发送

                // 等待 CVI3 的响应
                byte[] buffer0 = new byte[1024];
                int bytesRead0 = socket.getInputStream().read(buffer0);
                if (bytesRead0 == -1) {//|| true
                    log.info("开始通讯指令未收到响应：CVI3 未发送数据或连接已关闭");
//                    Map map = new HashMap();
//                    map.put("message", "···马头控制器4连接失败，重连···");
//                    String json = JSON.toJSONString(map);
//                    webSocketServer.sendToAllClient(json);
//                    executeHeartbeatLogic();
                    reconnectwaitingtime();
                    continue;
                } else {
                    // 将响应数据转换为字符串
                    String response0 = new String(buffer0, 0, bytesRead0, StandardCharsets.US_ASCII);
                    log.info("CVI3 初连响应: " + response0);
                    String resp = extractSubstring(response0, 4, 8);
                    if(resp.contains("0004")){
                        log.info("初连控制器4失败，重连");
//                        Map map = new HashMap();
//                        map.put("message", "···马头控制器4连接失败，重连···");
//                        String json = JSON.toJSONString(map);
//                        webSocketServer.sendToAllClient(json);
//                        executeHeartbeatLogic();
                        reconnectwaitingtime();
                        continue;
                    }
//                    else {
//                        Map map = new HashMap();
//                        map.put("message", "···马头控制器4连接成功···");
//                        String json = JSON.toJSONString(map);
//                        webSocketServer.sendToAllClient(json);
//                    }
                }

                int i = 0;

                Object carType = CacheUtil.getFromCache("carType2");
                String carTypeString = carType != null ? String.valueOf(carType).trim() : "";
                lastCarTypeString = carTypeString;
                log.info("lastCarTypeString初始是：" + lastCarTypeString);
                String programNumber;
                log.info("当前carTypeString是："+carTypeString);
                System.out.println("当前carTypeString是："+carTypeString);
                if(carTypeString.equals(carTypeProperties.getCamry())) {
                    programNumber = TransmittersMessage.Select_Program_Number
                            +ipProperties.getSelectProgramNumber1()+'\0';
//                    programNumber = ipProperties.getSelectProgramNumber1()+'\0';
                    log.info("凯美瑞订阅程序号一"+programNumber);
                } else if(carTypeString.equals(carTypeProperties.getLevin())) {
                    programNumber = TransmittersMessage.Select_Program_Number
                            +ipProperties.getSelectProgramNumber2()+'\0';
//                    programNumber = ipProperties.getSelectProgramNumber2()+'\0';
                    log.info("雷凌订阅程序号二"+programNumber);
                }else {
                    programNumber = TransmittersMessage.Select_Program_Number
                            +ipProperties.getSelectProgramNumber1()+'\0';
//                    programNumber = ipProperties.getSelectProgramNumber1()+'\0';
                    log.info("都不是，默认选择程序号一"+programNumber);
                }

                //重连代替复位
                out.write(programNumber.getBytes());
                out.flush();
                byte[] buffer5 = new byte[1024];
                int bytesRead5 = socket.getInputStream().read(buffer5);
                if (bytesRead5 == -1) {
                    log.info("4程序号选择失败，失去连接");
//                    Map map = new HashMap();
//                    map.put("message", "···马头控制器4程序号选择，重连···");
//                    String json = JSON.toJSONString(map);
//                    webSocketServer.sendToAllClient(json);
//                    executeHeartbeatLogic();
                    reconnectwaitingtime();
                    continue;
                } else {
                    // 将响应数据转换为字符串
                    String response5 = new String(buffer5, 0,
                            bytesRead5, StandardCharsets.US_ASCII);
                    log.info("CVI34 程序号选择响应: {}",response5);
                    String resp = extractSubstring(response5, 4, 8);
                    log.info("resp是:"+resp);
                    if(resp.contains("0004")){
                        log.info("4程序号选择失败，重连");
//                        Map map = new HashMap();
//                        map.put("message", "···马头控制器4程序选择失败，重连···");
//                        String json = JSON.toJSONString(map);
//                        webSocketServer.sendToAllClient(json);
//                        executeHeartbeatLogic();
                        reconnectwaitingtime();
                        continue;
                    }
//                    else {
//                        Map map = new HashMap();
//                        map.put("message", "···马头控制器4程序号选择成功···");
//                        String json = JSON.toJSONString(map);
//                        webSocketServer.sendToAllClient(json);
//                    }
                }


                out.write(TransmittersMessage.Subscribe_Torque_And_Angle.getBytes());
                out.flush();
                byte[] buffer3 = new byte[1024];
                int bytesRead3 = socket.getInputStream().read(buffer3);
                if (bytesRead3 == -1) {
                    log.info("订阅失败，失去连接");
//                    Map map = new HashMap();
//                    map.put("message", "···马头控制器4订阅失败，重连···");
//                    String json = JSON.toJSONString(map);
//                    webSocketServer.sendToAllClient(json);
//                    executeHeartbeatLogic();
                    reconnectwaitingtime();
                    continue;
                } else {
                    // 将响应数据转换为字符串
                    String response3 = new String(buffer3, 0,
                            bytesRead3, StandardCharsets.US_ASCII);
                    log.info("CVI34 订阅响应: {}",response3);
                    String resp = extractSubstring(response3, 4, 8);
                    if(resp.contains("0004")){
                        log.info("订阅指令失败");
//                        Map map = new HashMap();
//                        map.put("message", "···马头控制器4订阅失败，重连···");
//                        String json = JSON.toJSONString(map);
//                        webSocketServer.sendToAllClient(json);
//                        executeHeartbeatLogic();
                        reconnectwaitingtime();
                        continue;
                    }
//                    else {
//                        Map map = new HashMap();
//                        map.put("message", "···马头控制器4订阅成功···");
//                        String json = JSON.toJSONString(map);
//                        webSocketServer.sendToAllClient(json);
//                    }
                }


                int screwNum51;
                int screwNum52;
                int screwNum53;
                int screwNum54;
                //螺丝序号计数器
                Object screwNum51Cache = CacheUtil.getFromCache("screwNum51");
//                log.info("screwNum51Cache是",screwNum51Cache);
                if(screwNum51Cache == null){
                    log.info("新建screwNum51缓存");
                    CacheUtil.putInCache("screwNum51",0);
                    screwNum51 = 0;
                }else {
                    screwNum51 = (int)screwNum51Cache;
                }
                Object screwNum52Cache = CacheUtil.getFromCache("screwNum52");
                if(screwNum52Cache == null){
                    log.info("新建screwNum52缓存");
                    CacheUtil.putInCache("screwNum52",0);
                    screwNum52 = 0;
                }else {
                    screwNum52 = (int)screwNum52Cache;
                }
                Object screwNum53Cache = CacheUtil.getFromCache("screwNum53");
                if(screwNum53Cache == null){
                    log.info("新建screwNum53缓存");
                    CacheUtil.putInCache("screwNum53",0);
                    screwNum53 = 0;
                }else {
                    screwNum53 = (int)screwNum53Cache;
                }
                Object screwNum54Cache = CacheUtil.getFromCache("screwNum54");
                if(screwNum54Cache == null){
                    log.info("新建screwNum54缓存");
                    CacheUtil.putInCache("screwNum54",0);
                    screwNum54 = 0;
                }else {
                    screwNum54 = (int)screwNum54Cache;
                }

                String carNumCache1 = "";//用于判断什么时候重置螺丝序号
                String carTypeCache1 = "";
                String repeatCache1 = "";
                String carNumCache2 = "";//用于判断什么时候重置螺丝序号
                String carTypeCache2 = "";
                String repeatCache2 = "";

                // 使用 Arrays.asList 初始化一个包含特定元素的列表
                List<Integer> screwNum51List = Arrays.asList(5, 6, 7, 8, 1, 2, 3, 4);
                List<Integer> screwNum52List = Arrays.asList(5, 6, 7, 8, 1, 2, 3, 4);//13, 14, 15, 16, 9, 10, 11, 12
                List<Integer> screwNum53List = Arrays.asList(2, 1);
                List<Integer> screwNum54List = Arrays.asList(2, 1);
                int screwType51 = -1;
                int screwType52 = -1;
                int screwType53 = -1;
                int screwType54 = -1;
                while (true){

                    carTypeString = ReSelectParamgramNum(out,socket,lastCarTypeString);
                    if(carTypeString == null){
                        log.info("程序号选择失败，---break");
                        //程序号选择失败，跳出循环，重连
                        break;
                    }
                    lastCarTypeString = carTypeString;
                    log.info(carTypeString+"carTypeString赋值给lastCarTypeString：" + lastCarTypeString);


                    try {
                        // 发送第二条心跳命令（传入的command）
                        out.write(TransmittersMessage.Heartbeat.getBytes());
                        out.flush(); // 确保数据已经发送
                    } catch (SocketException e) {
                        // 重新建立连接逻辑
//                    reconnect(); // 实现一个重连方法
//                        executeHeartbeatLogic();
                        log.info("连接已关闭，---break", e.getMessage());
                        break; // 退出当前循环或继续
                    } catch (Exception e) {
//                        executeHeartbeatLogic();
                        // 捕获其他异常
                        e.printStackTrace();
                        log.info("心跳发送异常，---break");
                        break;
                    }
                    try {
                        i++;
                        log.info("心跳次数：{}",i);
                        byte[] buffer1 = new byte[1024];
                        int bytesRead1 = socket.getInputStream().read(buffer1);
                        if (bytesRead1 == -1) {
//                            log.info("心跳停止");
//                            Map map = new HashMap();
//                            map.put("message", "···马头控制器4心跳失败，重连···");
//                            String json = JSON.toJSONString(map);
//                            webSocketServer.sendToAllClient(json);
//                            executeHeartbeatLogic();
                            log.info("心跳停止，---break");
                            break;
                        } else {
                            // 将响应数据转换为字符串
                            String response1 = new String(buffer1, 0,
                                    bytesRead1, StandardCharsets.US_ASCII);
//                            log.info("CVI3 心跳响应: {}",response1);
                            String resp = extractSubstring(response1, 4, 8);
                            if(resp.contains("0004")){
//                                Map map = new HashMap();
//                                map.put("message", "···马头控制器4心跳失败，重连···");
//                                String json = JSON.toJSONString(map);
//                                webSocketServer.sendToAllClient(json);
//                                executeHeartbeatLogic();
                                log.info("心跳指令失败，---break");
                                break;
                            }else {
//                                if(test0>0) {
                                    CacheUtil.putInCache("controller4", "1");
//                                    Map map = new HashMap();
//                                    map.put("message0", "···马头控制器4心跳成功···");
//                                    String json = JSON.toJSONString(map);
//                                    webSocketServer.sendToAllClient(json);
//                                    test0 = 0;
//                                }
                            }
                            //截取拧紧枪号
                            // 要去掉的部分
                            String resp0 = "";
                            String extractGunNum = "";
                            if(response1.contains("0231")) {
                                String partToRemove = TransmittersMessage.HeartbeatRepay.trim();//"00209999001";
                                if (response1.contains(partToRemove)) {
                                    // 移除指定的部分
//                                log.info("移除..."+TransmittersMessage.HeartbeatRepay.trim());
                                    response1 = response1.replace(partToRemove, "").trim();
                                }
//                            log.info("移除指定的部分后:" + response1);
                                resp0 = extractSubstring(response1, 0, 4);
                                extractGunNum = extractSubstring(response1, 28, 30);
                                log.info("1检测到枪的编号是:"+extractGunNum);
                                //新增
                                if(extractGunNum.equals(gunProperties.getGun1())){
                                    extractGunNum = gunProperties.getGun4();
                                }
                            }

                            if(response1.contains("0231") && resp0.equals("0231") && extractGunNum.equals(gunProperties.getGun4())){
                                log.info("立即返回确认");
                                out.write(TransmittersMessage.Receive_Result.getBytes());
                                out.flush();

//                            String extractGunNum = extractSubstring(response1, 28, 30);//extractParts(response1);
//                            log.info("检测到枪的编号是:"+extractGunNum);
//                            String extractGunNum = String.valueOf(53);
//                            log.info("假数据枪的编号是:"+extractGunNum);
                                //截取扭力值
//                            String extractTorque00 = extractSubstring(response1, 140, 146);
//                            log.info("检测到extractTorque00是"+extractTorque00);//000098

                                Double extractTorque0 = Double.valueOf(extractSubstring(response1, 140, 146));

                                extractTorque0 = extractTorque0 * 0.01;
                                BigDecimal extractTorque1 = BigDecimal.valueOf(extractTorque0);
                                extractTorque1 = extractTorque1.setScale(2, RoundingMode.HALF_UP); // 保留两位小数，四舍五入

                                log.info("检测到螺丝的扭力是:"+extractTorque1);
                                if (extractTorque1.compareTo(new BigDecimal(ipProperties.getWorkShop2MiniTorque())) < 0) {
                                    // 当 extractTorque1 小于 3 时执行的逻辑
                                    log.warn("螺丝扭力不足！当前值: " + extractTorque1 + "，要求≥3");
                                    String errorMsg = String.format(
                                            "拧紧枪1扭力不足！要求≥%sN",ipProperties.getWorkShop2MiniTorque()
                                    );
                                    Map map = new HashMap();
                                    map.put("message", errorMsg);
                                    map.put("torque", extractTorque1); //扭力值是
                                    map.put("unit", MessageConstant.torqueUnit);
                                    String json = JSON.toJSONString(map);
                                    webSocketServer.sendToAllClient(json);
                                    continue;
                                }
                                // 将 BigDecimal 转换回 Double
                                double extractTorque = extractTorque1.doubleValue();
                                //截取合格标志
                                String extractFlag = extractSubstring(response1, 110, 111);
//                                log.info("检测到螺丝的合格标志是:"+extractFlag);//0=低，1=合格，2=高

                                //哪个程序号的枪发回来的数据
                                String programNum = extractSubstring(response1, 90, 93);
                                log.info("哪个程序号的枪发回来的数据:"+programNum);

                                LambdaQueryWrapper<WeldingGun> weldingGunQueryWrapper = new LambdaQueryWrapper<>();
                                weldingGunQueryWrapper.eq(WeldingGun::getWeldingGunId, extractGunNum);
                                WeldingGun weldingGun;
                                if(weldingGunMapper.selectCount(weldingGunQueryWrapper) == 0){
                                    //找不到该拧紧枪的信息，
                                    weldingGun = new WeldingGun();
                                    weldingGun.setWeldingGunId(Long.valueOf(extractGunNum));

                                    if (extractGunNum.equals(gun1Num) || extractGunNum.equals(gun2Num)) {
                                        weldingGun.setWorkingPositionId(MessageConstant.workingPosition1);
                                    } else if (extractGunNum.equals(gun3Num) || extractGunNum.equals(gun4Num)) {
                                        weldingGun.setWorkingPositionId(MessageConstant.workingPosition2);
                                    } else {
                                        // Optional: 可以在这里处理未匹配的情况，或者恢复默认值
                                        log.info("未配对的枪: " + extractGunNum);
                                        weldingGun.setWorkingPositionId(MessageConstant.workingPosition1);
                                    }
//                                switch (extractGunNum) {
//                                    case gun1Num://
//                                    case gun2Num:
//                                        weldingGun.setWorkingPositionId(Long.valueOf(MessageConstant.workingPosition1));
//                                        break;
//                                    case gun3Num:
//                                    case gun4Num:
//                                        weldingGun.setWorkingPositionId(Long.valueOf(MessageConstant.workingPosition2));
//                                        break;
//                                    default:
//                                        // Optional: 可以在这里处理未匹配的情况，或者恢复默认值
//                                        log.info("未配对的枪: " + extractGunNum);
//                                        break;
//                                }
                                    weldingGunService.save(weldingGun);
//                                log.info("立即就能获取到拧紧枪的id?:"+weldingGun.getId());
                                }
//                            else{
//                                //数据库里已经有了这个枪的信息了
//                                //System.out.println("数据库里已经有了这把枪的信息了");
////                                weldingGun = weldingGunMapper.selectOne(weldingGunQueryWrapper);
//                            }

                                String carNum1 = (String) CacheUtil.getFromCache("carNum1");
                                String carType1 = (String) CacheUtil.getFromCache("carType1");
                                String repeat1 = (String) CacheUtil.getFromCache("repeat1");

                                String carNum2 = (String) CacheUtil.getFromCache("carNum2");
                                String carType2 = (String) CacheUtil.getFromCache("carType2");
                                String repeat2 = (String) CacheUtil.getFromCache("repeat2");

                                //System.out.println("拿到车1的缓存: "+carNum1+carType1+repeat1);
                                //System.out.println("拿到车2的缓存: "+carNum2+carType2+repeat2);

                                Screw screw = new Screw();

//                            String extractCacheGunNumString = "";//把原来的枪号缓存起来
//                            CacheUtil.putInCache("extractCacheGunNum",);


//                            if((carNum1 != null && !carNum1.equals(carNumCache1)) ||
//                                    (carType1 != null && !carType1.equals(carTypeCache1)) ||
//                                    (repeat1 != null && !repeat1.equals(repeatCache1))){

                                if(!carNum1.equals(carNumCache1) ||
                                        !carType1.equals(carTypeCache1) ||
                                        !repeat1.equals(repeatCache1)){
                                    //车身号缓存变了，说明流水线向下走了一格，重置螺丝号计算
                                    log.info("1重置螺丝号");
                                    screwNum51 = 0;
                                    screwNum52 = 0;
                                    CacheUtil.putInCache("screwNum51",0);
                                    CacheUtil.putInCache("screwNum52",0);
                                }
                                //工位一没数据时，拧一下就弹窗
                                if((carNum1 == null && carType1 == null && repeat1 == null) ||
                                        (carNum1.isEmpty() && carType1.isEmpty() && repeat1.isEmpty()) ||
                                        carNum1.contains("null") ||
                                        carType1.equals("未知车型")){
                                    TorqueStandards torqueStandards = null;
//                                CacheUtil.putInCache("extractCacheGunNum1",extractGunNum);
//                                extractCacheGunNum = extractGunNum;
                                    String extractGunNum0 = String.valueOf(1);
                                    sendToAllClient(extractGunNum0, extractTorque, torqueStandards);
                                }
//                            log.info("carNum2是"+carNum2);
//                            log.info("carNumcache2是"+carNumCache2);
//                            if((carNum2 != null && !carNum2.equals(carNumCache2)) ||
//                                    (carType2 != null && !carType2.equals(carTypeCache2)) ||
//                                    (repeat2 != null && !repeat2.equals(repeatCache2))){
                                if(!carNum2.equals(carNumCache2) ||
                                        !carType2.equals(carTypeCache2) ||
                                        !repeat2.equals(repeatCache2)){
                                    //车身号缓存变了，说明流水线向下走了一格，重置螺丝号计算
                                    log.info("2重置螺丝号");
                                    screwNum53 = 0;
                                    screwNum54 = 0;
                                    CacheUtil.putInCache("screwNum53",0);
                                    CacheUtil.putInCache("screwNum54",0);
                                }
                                //工位二没数据时，拧一下就弹窗
                                if((carNum2 == null && carType2 == null && repeat2 == null) ||
                                        (carNum2.isEmpty() && carType2.isEmpty() && repeat2.isEmpty()) ||
                                        carNum2.contains("null") ||
                                        carType2.equals("未知车型")){
                                    TorqueStandards torqueStandards = null;
//                                CacheUtil.putInCache("extractCacheGunNum2",extractGunNum);
//                                extractCacheGunNum = extractGunNum;
                                    String extractGunNum0 = String.valueOf(2);
                                    sendToAllClient(extractGunNum0, extractTorque, torqueStandards);
                                }
                                carNumCache1 = carNum1;
                                carTypeCache1 = carType1;
                                repeatCache1 = repeat1;
                                carNumCache2 = carNum2;
                                carTypeCache2 = carType2;
                                repeatCache2 = repeat2;
                                LambdaQueryWrapper<screwType> screwTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
                                screwTypeLambdaQueryWrapper.eq(screwType::getWeldingGunId,extractGunNum);


                                Object standard1 = CacheUtil.getFromCache("standard1");
                                Object standard2 = CacheUtil.getFromCache("standard2");

                                if (extractGunNum.equals(gun1Num) && standard1 != null) {
                                    // screw.setWeldingGunId(weldingGun.getId());
                                    if(screwNum51List.size() >= 8 && screwNum51 < screwNum51List.size()) {
                                        screwType51 = screwNum51List.get(screwNum51);
                                        screwNum51++;
                                        log.info("枪 " + gun1Num +
                                                " 螺丝序号是: " + screwNum51 +
                                                "螺丝类型号：" + screwType51);
                                        screwTypeLambdaQueryWrapper.eq(screwType::getScrewId, screwType51);
                                    }
                                } else if (extractGunNum.equals(gun2Num) && standard1 != null) {
                                    // screw.setWeldingGunId(weldingGun.getId());
                                    if(screwNum52List.size() >= 8 && screwNum52 < screwNum52List.size()) {
                                        screwType52 = screwNum52List.get(screwNum52);
                                        screwNum52++;
                                        log.info("枪 " + gun2Num +
                                                " 螺丝序号是: " + screwNum52 +
                                                "螺丝类型号：" + screwType52);
                                        screwTypeLambdaQueryWrapper.eq(screwType::getScrewId, screwType52);
                                    }
                                } else if (extractGunNum.equals(gun3Num) && standard2 != null) {
                                    // screw.setWeldingGunId(weldingGun.getId());
                                    if(screwNum53List.size() >= 2 && screwNum53 < screwNum53List.size()) {
                                        screwType53 = screwNum53List.get(screwNum53);
                                        screwNum53++;
                                        log.info("枪 " + gun3Num +
                                                " 螺丝序号是: " + screwNum53 +
                                                "螺丝类型号：" + screwType53);
                                        screwTypeLambdaQueryWrapper.eq(screwType::getScrewId, screwType53);
                                    }
                                } else if (extractGunNum.equals(gun4Num) && standard2 != null) {
                                    // screw.setWeldingGunId(weldingGun.getId());
                                    if(screwNum54List.size() >= 2 && screwNum54 < screwNum54List.size()) {
                                        screwType54 = screwNum54List.get(screwNum54);
                                        screwNum54++;
                                        log.info("枪 " + gun4Num +
                                                " 螺丝序号是: " + screwNum54 +
                                                "螺丝类型号：" + screwType54);
                                        screwTypeLambdaQueryWrapper.eq(screwType::getScrewId, screwType54);
                                    }
                                } else {
                                    // 处理未匹配的情况
                                    log.info("未配对的枪");
                                    TorqueStandards torqueStandards = null;
//                                Object extractCacheGunNum1 = CacheUtil.getFromCache("extractCacheGunNum1");
//                                Object extractCacheGunNum2 = CacheUtil.getFromCache("extractCacheGunNum2");
//                                log.info("extractCacheGunNum1是"+extractCacheGunNum1);
//                                log.info("extractCacheGunNum2是"+extractCacheGunNum2);
//                                if((extractCacheGunNum1 != null && extractCacheGunNum1 != "") ||
//                                        (extractCacheGunNum2 != null && extractCacheGunNum2 != "")){
//                                    extractCacheGunNumString = String.valueOf(extractCacheGunNum1);
//                                    //清空缓存，本次循环只是提醒枪号未识别，避免下一次
//                                    CacheUtil.putInCache("extractCacheGunNum1","");
//                                    CacheUtil.putInCache("extractCacheGunNum2","");
//                                }else{//== null证明前面识别到了车的信息
//                                    extractCacheGunNumString = String.valueOf(extractGunNum);
//                                }
                                    //排除掉工位一二的无数据弹窗，本次循环只弹枪号未识别弹窗
                                    if(!extractGunNum.equals(String.valueOf(1)) && !extractGunNum.equals(String.valueOf(2))){
                                        sendToAllClient(extractGunNum,extractTorque,torqueStandards);
                                    }
                                }

                                if(carType1 != null &&
                                        (extractGunNum.equals(gun1Num) ||
                                                extractGunNum.equals(gun2Num))){
                                    log.info("工位一开始录入信息");
                                    //读取监控到的车的Id
                                    LambdaQueryWrapper<Car> carLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                                    carLambdaQueryWrapper.eq(Car::getCarId, carNum1.trim());
//                                    carLambdaQueryWrapper.eq(Car::getCarType, carType1.trim());
//                                    carLambdaQueryWrapper.eq(Car::getRepeatNum, repeat1.trim());

                                    carLambdaQueryWrapper.eq(Car::getWorkingPositionId, MessageConstant.workingPosition1) // 只限制工位
                                            .orderByDesc(Car::getCreateTime) // 按时间降序（最新的在前）
                                            .last("LIMIT 1"); // 取最新的一条
                                    Car car = carMapper.selectOne(carLambdaQueryWrapper);
                                    //无数据时：返回 null；

                                    //如果最新那条是读到的车，就用他的Id作为螺丝的carId，否则则认为车数据还没录入，continue跳过
                                    if(car != null &&
                                            !carNum1.trim().isEmpty() &&
                                            !carType1.trim().isEmpty() &&
                                            !repeat1.trim().isEmpty() &&
                                            !carType1.trim().equals("未知车型") &&
                                            !carNum1.trim().contains("null")) {
                                        if(car.getCarId().equals(carNum1.trim()) &&
                                                car.getCarType().equals(carType1.trim()) &&
                                                car.getRepeatNum().equals(repeat1.trim())){
                                            screw.setCarId(car.getId());
                                        }else {
                                            log.info("车数据未录入");
                                            Map map = new HashMap();
                                            map.put("message", "--当前车辆未就位--");
                                            String json = JSON.toJSONString(map);
                                            webSocketServer.sendToAllClient(json);
                                            continue;
                                        }
                                    }else {
                                        log.info("数据库无数据/未知车型/车身号前缀未设置");
                                        Map map = new HashMap();
                                        map.put("message", "--数据库无数据--\n--未知车型--\n--车身号前缀未设置--");
                                        String json = JSON.toJSONString(map);
                                        webSocketServer.sendToAllClient(json);
                                        continue;
                                    }

//                                    carLambdaQueryWrapper.eq(Car::getCarId, carNum1.trim())
//                                            .eq(Car::getCarType, carType1.trim())
//                                            .eq(Car::getRepeatNum, repeat1.trim())
//                                            // 按时间字段降序排序（最新的排在前面）
//                                            .orderByDesc(Car::getCreateTime)
//                                            // 限制只查询1条（取最新的那条）
//                                            .last("LIMIT 1");
//                                    Integer count1 = carMapper.selectCount(carLambdaQueryWrapper);
//                                    Car car = new Car();
//                                    if(count1 > 1){
//                                        log.info("数据库中存在"+carNum1+"这辆车");
//                                        //删除所有，重新插入，(重新插入)只留下一条
//                                        //carMapper.delete(carLambdaQueryWrapper);
//                                        //取最新的那条
//                                        carLambdaQueryWrapper.orderByDesc(Car::getCreateTime);
//                                        carLambdaQueryWrapper.last("LIMIT 1");
//                                        List<Car> carList = carMapper.selectList(carLambdaQueryWrapper);
////                                    Car car = new Car();
////                                        if(carList != null) {
//                                        if(!carList.isEmpty()) {
//                                            car = carList.get(0);
//                                            screw.setCarId(car.getId());
//                                        }
//
//                                    }else if(count1 == 1){
//                                        car = carMapper.selectOne(carLambdaQueryWrapper);
//                                        log.info("有"+carNum1.trim()+"这辆车的数据...工位一");
//                                        screw.setCarId(car.getId());
//                                    }
//                                    else if(count1 == 0 &&
//                                            (!carNum1.trim().isEmpty() ||
//                                                    !carType1.trim().isEmpty() ||
//                                                    !repeat1.trim().isEmpty())){
////                                        car = new Car();
//                                        log.info("没有"+carNum1.trim()+"这辆车的数据...工位一");
////                                        car.setCarId(carNum1);
////                                        car.setCarType(carType1);
////                                        car.setRepeatNum(repeat1);
////                                        car.setWorkingPositionId(MessageConstant.workingPosition1);
//                                        if(!carType1.trim().equals("未知车型") &&
//                                                !carNum1.trim().contains("null")) {
////                                            carService.save(car);
//                                            Map map = new HashMap();
//                                            map.put("message", "--当前车辆未就位--");
//                                            String json = JSON.toJSONString(map);
//                                            webSocketServer.sendToAllClient(json);
//                                            continue;
//                                        }
//                                        screw.setCarId(car.getId());
//                                    }


                                    screw.setTorque(extractTorque);
                                    screw.setUnit(MessageConstant.torqueUnit);
                                    screw.setWorkingPositionId(MessageConstant.workingPosition1);
                                    Integer count = screwTypeMapper.selectCount(screwTypeLambdaQueryWrapper);
                                    screwType screwType = null;
                                    if(count == 1) {
                                        screwType = screwTypeMapper.selectOne(screwTypeLambdaQueryWrapper);
                                    }
                                    if(screwType != null){
                                        screw.setScrewTypeId(screwType.getId());
                                    }

                                    TorqueStandards torqueStandards = null;
                                    if(standard1 != null){
                                        torqueStandards = (TorqueStandards) standard1;
                                    }else {
                                        extractGunNum = String.valueOf(3);
                                    }

                                    //!extractFlag.equals("1") ||
                                    log.info("extractTorque:"+extractTorque);
                                    log.info("extractTorque:"+torqueStandards.getMaximumTorque());
//                                if(extractTorque < torqueStandards.getMaximumTorque() ||
//                                        extractTorque > torqueStandards.getMinimumTorque()) {
                                    log.info("工位一插入报警信息"+screwNum51+screwNum52);//screwNum51
                                    if (screwNum51 <= MessageConstant.carScrewLimit &&
                                            screwType51 <= MessageConstant.carScrewLimit &&
                                            screwType51 >= 1 &&
                                            extractGunNum.equals(gun1Num) && screwType != null &&
                                            torqueStandards != null) {
                                        // 这里会运行在事务环境中
//                                            HeartBeatQuartz proxy = applicationContext.getBean(HeartBeatQuartz.class);
//                                            proxy.
                                        operationJDBC(MessageConstant.workingPosition1, screwType, car, screw, extractFlag,
                                                extractTorque, torqueStandards, extractGunNum, screwNum51);

                                    } else if (screwNum52 <= MessageConstant.carScrewLimit &&
                                            screwType52 <= MessageConstant.carScrewLimit &&
                                            screwType52 >= 1 &&
                                            extractGunNum.equals(gun2Num) && screwType != null && torqueStandards != null) {
                                        // 这里会运行在事务环境中
//                                            HeartBeatQuartz proxy = applicationContext.getBean(HeartBeatQuartz.class);
//                                            proxy.
                                        operationJDBC(MessageConstant.workingPosition1, screwType, car, screw, extractFlag,
                                                extractTorque, torqueStandards, extractGunNum, screwNum52);
                                    } else {//拧紧次数超过，提示扭力
                                        sendToAllClient(extractGunNum, extractTorque, torqueStandards);
                                    }
//                                }
                                    //三四号枪录入的是工位二的车信息，工位二的车的螺丝
                                }else if(carType2 != null &&
                                        (extractGunNum.equals(gun3Num) ||
                                                extractGunNum.equals(gun4Num))){
                                    log.info("工位二开始录入信息");
                                    if(carNum2.trim().isEmpty() ||
                                            carType2.trim().isEmpty() ||
                                            repeat2.trim().isEmpty() ||
                                            carType2.trim().equals("未知车型") ||
                                            carNum2.trim().contains("null")){
                                        log.info("数据库无数据/未知车型/车身号前缀未设置");
                                        Map map = new HashMap();
                                        map.put("message", "--数据库无数据--\n--未知车型--\n--车身号前缀未设置--");
                                        String json = JSON.toJSONString(map);
                                        webSocketServer.sendToAllClient(json);
                                        continue;
                                    }

                                    //读取监控到的车的Id
//                                    LambdaQueryWrapper<Car> carLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                                    carLambdaQueryWrapper.eq(Car::getCarId, carNum2);
//                                    carLambdaQueryWrapper.eq(Car::getCarType, carType2);
//                                    carLambdaQueryWrapper.eq(Car::getRepeatNum, repeat2);

                                    //优化前：
//                                    Object fourTimes = CacheUtil.getFromCache("4times");
//                                    int fourTimesInt = 0;
//                                    if(fourTimes != null){
//                                        fourTimesInt = Integer.parseInt(fourTimes.toString().trim());
//                                    }else {
//                                        //4次缓存没有读到，则不处理
//                                        continue;
//                                    }
//
//                                    if(fourTimesInt > 0) {
//                                        LambdaQueryWrapper<Car> carLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                                        //前四次取盘的，1.工位二的数据可能会存入数据库，取数据库工位二最新的
//                                        carLambdaQueryWrapper.eq(Car::getWorkingPositionId, MessageConstant.workingPosition2) // 只限制工位
//                                                .orderByDesc(Car::getCreateTime) // 按时间降序（最新的在前）
//                                                .last("LIMIT 1"); // 取数据库工位二最新的
//                                        Car lastedCar = carMapper.selectOne(carLambdaQueryWrapper);
//
//                                        //如果最新那条是读到的车，就用他的Id作为螺丝的carId，否则则认为车数据还没录入，continue跳过
//                                        if(lastedCar != null) {
//                                            if(lastedCar.getCarId().equals(carNum1.trim()) &&
//                                                    lastedCar.getCarType().equals(carType1.trim()) &&
//                                                    lastedCar.getRepeatNum().equals(repeat1.trim())){
//                                                //能进到这里证明当前工位二读到的盘的数据就是数据库工位二最新的
//                                                screw.setCarId(lastedCar.getId());
//                                            }else {
//                                                //2.工位二的数据可能不是立即存入数据库的，是以前工位一存入的数据，取数据库工位一倒数第四条
//                                                log.info("工位二车数据未录入，工位二读到的是工位一录入的数据（倒数第四条）");//取数据库工位一倒数第四条
//                                                LambdaQueryWrapper<Car> carLambdaQueryWrapper0 = new LambdaQueryWrapper<>();
//                                                carLambdaQueryWrapper0.eq(Car::getWorkingPositionId, MessageConstant.workingPosition1)
//                                                        .orderByDesc(Car::getCreateTime)
//                                                        .last("LIMIT 3, 1");
//                                                Car lastedCar0 = carMapper.selectOne(carLambdaQueryWrapper0);
//                                                if(lastedCar0 == null){
//                                                    log.info("数据库无数据/未知车型/车身号前缀未设置");
//                                                    Map map = new HashMap();
//                                                    map.put("message", "--数据库无数据--\n--未知车型--\n--车身号前缀未设置--");
//                                                    String json = JSON.toJSONString(map);
//                                                    webSocketServer.sendToAllClient(json);
//                                                    continue;
//                                                }
//                                                //能进到这里证明当前工位二读到的是工位一录入的数据（倒数第四条）
//                                                screw.setCarId(lastedCar0.getId());
//                                            }
//                                        } else {
//                                            //2.数据库里完全没有工位二的数据，是以前工位一存入的数据，取数据库工位一倒数第四条
//                                            LambdaQueryWrapper<Car> carLambdaQueryWrapper0 = new LambdaQueryWrapper<>();
//                                            carLambdaQueryWrapper0.eq(Car::getWorkingPositionId, MessageConstant.workingPosition1)
//                                                    .orderByDesc(Car::getCreateTime)
//                                                    .last("LIMIT 3, 1");
//                                            Car lastedCar0 = carMapper.selectOne(carLambdaQueryWrapper0);
//                                            if(lastedCar0 == null){
//                                                log.info("数据库无数据/未知车型/车身号前缀未设置");
//                                                Map map = new HashMap();
//                                                map.put("message", "--数据库无数据--\n--未知车型--\n--车身号前缀未设置--");
//                                                String json = JSON.toJSONString(map);
//                                                webSocketServer.sendToAllClient(json);
//                                                continue;
//                                            }
//                                            //能进到这里证明当前工位二读到的是工位一录入的数据（倒数第四条）
//                                            screw.setCarId(lastedCar0.getId());
//                                        }
//                                    }else {
//                                        //3.四次之后取数据库工位一倒数第四条
//                                        LambdaQueryWrapper<Car> carLambdaQueryWrapper0 = new LambdaQueryWrapper<>();
//                                        carLambdaQueryWrapper0.eq(Car::getWorkingPositionId, MessageConstant.workingPosition1)
//                                                .orderByDesc(Car::getCreateTime)
//                                                .last("LIMIT 3, 1");
//                                        Car lastedCar0 = carMapper.selectOne(carLambdaQueryWrapper0);
//                                        if(lastedCar0 == null){
//                                            log.info("数据库无数据/未知车型/车身号前缀未设置");
//                                            Map map = new HashMap();
//                                            map.put("message", "--数据库无数据--\n--未知车型--\n--车身号前缀未设置--");
//                                            String json = JSON.toJSONString(map);
//                                            webSocketServer.sendToAllClient(json);
//                                            continue;
//                                        }
//                                        //能进到这里证明当前工位二读到的是工位一录入的数据（倒数第四条）
//                                        screw.setCarId(lastedCar0.getId());
//                                    }

                                    //--------------------------------------

                                    //优化后
                                    // 3. 核心业务逻辑（优化后）
                                    Object fourTimesObj = CacheUtil.getFromCache(CACHE_KEY_4TIMES);
                                    int fourTimesInt = 0;
// 处理缓存值转换（使用Optional简化null判断）
                                    fourTimesInt = Optional.ofNullable(fourTimesObj)
                                            .map(obj -> obj.toString().trim())
                                            .map(str -> {
                                                try {
                                                    return Integer.parseInt(str);
                                                } catch (NumberFormatException e) {
                                                    log.warn("缓存4times值不是有效整数：{}", str);
                                                    return 0;
                                                }
                                            })
                                            .orElse(0);
// 四次以内的逻辑
                                    Car car = new Car();
                                    if (fourTimesInt > 0) {
                                        // 查询工位二最新记录
                                        LambdaQueryWrapper<Car> wp2Query = new LambdaQueryWrapper<>();
                                        wp2Query.eq(Car::getWorkingPositionId, MessageConstant.workingPosition2)
                                                .orderByDesc(Car::getCreateTime)
                                                .last("LIMIT 1");
                                        Car latestWp2Car = carMapper.selectOne(wp2Query);

                                        // 检查工位二最新记录是否匹配
                                        if (latestWp2Car != null) {
                                            // 增加属性非空判断（避免NPE）
                                            boolean idMatch = StringUtils.equals(latestWp2Car.getCarId(), carNum2.trim());
                                            boolean typeMatch = StringUtils.equals(latestWp2Car.getCarType(), carType2.trim());
                                            boolean repeatMatch = StringUtils.equals(latestWp2Car.getRepeatNum(), repeat2.trim());

                                            if (idMatch && typeMatch && repeatMatch) {
                                                // 匹配：使用工位二最新记录的ID
                                                screw.setCarId(latestWp2Car.getId());
                                                car = latestWp2Car;
                                                log.info("工位二前四次的数据录入数据库了");
//                                                continue; // 处理完成，进入下一轮
                                            }else {
                                                log.info("工位二车数据未录入或不匹配，跳过，等待工位二该数据录入？？？");//使用工位一倒数第四条数据还是跳过，等待工位二该数据录入
                                                continue;
                                            }
                                        }else {
                                            // 工位二记录不匹配或不存在：查询工位一倒数第四条
                                            log.info("工位二车数据未录入或不匹配，使用工位一倒数第四条数据");
                                            car = getWorkPosition1Last4thCar();
                                            if (car == null) {
                                                log.info("getWorkPosition1Last4thCar是:"+ERROR_MESSAGE);
                                                sendErrorMessage();
                                                continue;
                                            }
                                            screw.setCarId(car.getId());
                                        }
// 四次及以上的逻辑
                                    } else {
                                        // 直接查询工位一倒数第四条
                                        car = getWorkPosition1Last4thCar();
                                        if (car == null) {
                                            log.info("getWorkPosition1Last4thCar是:"+ERROR_MESSAGE);
                                            sendErrorMessage();
                                            continue;
                                        }
                                        screw.setCarId(car.getId());
                                    }

//---------------------------------------------------------

                                    screw.setTorque(extractTorque);
                                    screw.setUnit(MessageConstant.torqueUnit);
                                    screw.setWorkingPositionId(MessageConstant.workingPosition2);
                                    Integer count = screwTypeMapper.selectCount(screwTypeLambdaQueryWrapper);
                                    screwType screwType = null;
                                    if(count == 1) {
                                        screwType = screwTypeMapper.selectOne(screwTypeLambdaQueryWrapper);
                                    }
                                    if(screwType != null){//51
                                        screw.setScrewTypeId(screwType.getId());
                                    }

//                                //三枪的计数器 <=2  四枪的计数器 <=2
//                                if((screwNum53 <= MessageConstant.carHeadScrewLimit && extractGunNum.equals(gun3Num)) ||
//                                        (screwNum54 <= MessageConstant.carHeadScrewLimit && extractGunNum.equals(gun4Num))){
//                                    if(screwType != null){
//                                        screw.setScrewTypeId(screwType.getId());
//                                    }
//                                    LambdaQueryWrapper<Screw> screwLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                                    screwLambdaQueryWrapper.eq(Screw::getCarId, screw.getCarId());
//                                    screwLambdaQueryWrapper.eq(Screw::getScrewTypeId, screw.getScrewTypeId());
//                                    Integer count = screwMapper.selectCount(screwLambdaQueryWrapper);
//                                    log.info("count是-"+count);
//                                    if(count == 0){
//                                        screwService.save(screw);
//                                    }
//                                    if(count == 1){
//                                        screw = screwMapper.selectOne(screwLambdaQueryWrapper);
//                                    }
//                                }

                                    //工位2插入报警信息sendToAllClient
//                                LambdaQueryWrapper<TorqueStandards> torqueStandardsLambdaQueryWrapper = new LambdaQueryWrapper<>();
//                                torqueStandardsLambdaQueryWrapper.eq(TorqueStandards::getWorkingPositionId, MessageConstant.workingPosition2);
//                                TorqueStandards torqueStandards = torqueStandardsMapper.selectOne(torqueStandardsLambdaQueryWrapper);

//                                Object standard2 = CacheUtil.getFromCache("standard2");
//                                TorqueStandards torqueStandards = standard2 == null ? null : (TorqueStandards) standard2;
                                    TorqueStandards torqueStandards = null;
                                    if(standard2 != null){
                                        torqueStandards = (TorqueStandards) standard2;
                                    }else {
                                        extractGunNum = String.valueOf(3);
                                    }

//                                log.info("extractFlag是:{}",extractFlag);
//                                !extractFlag.equals("1") ||
//                                if(extractTorque > torqueStandards.getMaximumTorque() ||
//                                        extractTorque < torqueStandards.getMinimumTorque()) {
                                    log.info("工位二插入报警信息"+screwNum53+screwNum54);//screwNum53
                                    if (screwNum53 <= MessageConstant.carHeadScrewLimit &&
                                            screwType53 <= MessageConstant.carHeadScrewLimit &&
                                            screwType53 >= 1 &&
                                            extractGunNum.equals(gun3Num) && screwType != null && torqueStandards != null) {
                                        // 这里会运行在事务环境中
//                                            HeartBeatQuartz proxy = applicationContext.getBean(HeartBeatQuartz.class);
//                                            proxy.
                                        operationJDBC(MessageConstant.workingPosition2, screwType, car,
                                                screw, extractFlag,
                                                extractTorque, torqueStandards, extractGunNum, screwNum53);
                                    } else if (screwNum54 <= MessageConstant.carHeadScrewLimit &&
                                            screwType54 <= MessageConstant.carHeadScrewLimit &&
                                            screwType54 >= 1 &&
                                            extractGunNum.equals(gun4Num) && screwType != null && torqueStandards != null) {
                                        // 这里会运行在事务环境中
//                                            HeartBeatQuartz proxy = applicationContext.getBean(HeartBeatQuartz.class);
//                                            proxy.
                                        operationJDBC(MessageConstant.workingPosition2, screwType, car,
                                                screw, extractFlag,
                                                extractTorque, torqueStandards, extractGunNum, screwNum54);
                                    } else {
                                        sendToAllClient(extractGunNum, extractTorque, torqueStandards);
                                    }
//                                }
                                }

                            }
                        }
                        // 设置每次循环的等待时间（以毫秒为单位，例如：1000毫秒=1秒）
                        Thread.sleep(frequencyProperties.getHeartBeatFrequency4());//MessageConstant.heartBeatFrequency
                    } catch (InterruptedException e) {
                        // 处理 InterruptedException，通常是因为线程被中断
                        Thread.currentThread().interrupt(); // 重新设置中断标志
                        log.info("线程被中断，---break");
                        break; // 或者采取其他处理措施
                    }
                }
            } catch (ConnectException e) {
                try {
                    Thread.sleep(frequencyProperties.getHeartBeatFrequency0()
                            +frequencyProperties.getHeartBeatFrequency4());
                } catch (InterruptedException ex) {
//                    throw new RuntimeException(ex);
                    e.printStackTrace();
                }
                System.err.println("CVI连接4失败，错误信息: " + e.getMessage());
//                if(test == 1) {
                    CacheUtil.putInCache("controller4", "0");
//                    Map map = new HashMap();//马头控制器4心跳成功
//                    map.put("message0", "···未检测到马头控制器4···");//····未检测到马头控制器4····
//                    String json = JSON.toJSONString(map);
//                    webSocketServer.sendToAllClient(json);
//                    test--;
//                }
            } catch (Exception e) {
                System.err.println("CVI连接4失败，错误信息: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }


    private String ReSelectParamgramNum(OutputStream out, Socket socket,String lastCarTypeString) throws IOException {
        Object carType = CacheUtil.getFromCache("carType2");
        String carTypeString = carType != null ? String.valueOf(carType).trim() : "";
        log.info(carTypeString+"：carTypeString对比lastCarTypeString：" + lastCarTypeString);
        if(!lastCarTypeString.equals(carTypeString)) {
            log.info("----------------------2车型有变----------------------------------");
            String programNumber;
            log.info("当前carTypeString是：" + carTypeString);
            System.out.println("当前carTypeString是：" + carTypeString);
            if (carTypeString.equals(carTypeProperties.getCamry())) {
                    programNumber = TransmittersMessage.Select_Program_Number
                            +ipProperties.getSelectProgramNumber1()+'\0';
//                programNumber = ipProperties.getSelectProgramNumber1() + '\0';
                log.info("凯美瑞订阅程序号一" + programNumber);
//                System.out.println("凯美瑞订阅程序号一：" + programNumber);
            } else if (carTypeString.equals(carTypeProperties.getLevin())) {
                    programNumber = TransmittersMessage.Select_Program_Number
                            +ipProperties.getSelectProgramNumber2()+'\0';
//                programNumber = ipProperties.getSelectProgramNumber2() + '\0';
                log.info("雷凌订阅程序号二" + programNumber);
//                System.out.println("雷凌订阅程序号二：" + programNumber);
            } else {
                programNumber = TransmittersMessage.Select_Program_Number
                        +ipProperties.getSelectProgramNumber1()+'\0';
//                programNumber = ipProperties.getSelectProgramNumber1() + '\0';
                log.info("都不是，默认选择程序号一" + programNumber);
//                System.out.println("都不是，默认选择程序号一：" + programNumber);
            }

            //重连代替复位
//                executeHeartbeatLogic();
//                out.write(firstCommand.getBytes());
//                out.flush();
//            log.info("等待 CVI3 的响应");
            out.write(programNumber.getBytes());
            out.flush();
            byte[] buffer5 = new byte[1024];
            int bytesRead5 = socket.getInputStream().read(buffer5);
            if (bytesRead5 == -1) {
                log.info("--------------------------------------程序号选择失败-----------------------------------");
                log.info("4程序号选择失败，失去连接");
//            Map map = new HashMap();
//            map.put("message", "···马头控制器4程序号选择，重连···");
//            String json = JSON.toJSONString(map);
//            webSocketServer.sendToAllClient(json);
//                executeHeartbeatLogic();
                return null;
            } else {
                // 将响应数据转换为字符串
                String response5 = new String(buffer5, 0,
                        bytesRead5, StandardCharsets.US_ASCII);
                log.info("CVI34 程序号选择响应: {}", response5);
                String resp = extractSubstring(response5, 4, 8);
                log.info("resp是:" + resp);
                if (resp.contains("0004")) {
                    log.info("4程序号选择失败，重连");
//                Map map = new HashMap();
//                map.put("message", "···马头控制器4程序选择失败，重连···");
//                String json = JSON.toJSONString(map);
//                webSocketServer.sendToAllClient(json);
//                    executeHeartbeatLogic();
                    return null;
                }
//                else {
//                Map map = new HashMap();
//                map.put("message", "···马头控制器4程序号选择成功···");
//                String json = JSON.toJSONString(map);
//                webSocketServer.sendToAllClient(json);
//                }
            }
        }
        return carTypeString;
//        out.write(TransmittersMessage.Subscribe_Torque_And_Angle.getBytes());
//        out.flush();
//        byte[] buffer3 = new byte[1024];
//        int bytesRead3 = socket.getInputStream().read(buffer3);
//        if (bytesRead3 == -1) {
//            log.info("订阅失败，失去连接");
////            Map map = new HashMap();
////            map.put("message", "···马头控制器4订阅失败，重连···");
////            String json = JSON.toJSONString(map);
////            webSocketServer.sendToAllClient(json);
//            executeHeartbeatLogic();
//        } else {
//            // 将响应数据转换为字符串
//            String response3 = new String(buffer3, 0,
//                    bytesRead3, StandardCharsets.US_ASCII);
//            log.info("CVI34 订阅响应: {}",response3);
//            String resp = extractSubstring(response3, 4, 8);
//            if(resp.contains("0004")){
//                log.info("订阅指令失败");
////                Map map = new HashMap();
////                map.put("message", "···马头控制器4订阅失败，重连···");
////                String json = JSON.toJSONString(map);
////                webSocketServer.sendToAllClient(json);
//                executeHeartbeatLogic();
//            }else {
////                Map map = new HashMap();
////                map.put("message", "···马头控制器4订阅成功···");
////                String json = JSON.toJSONString(map);
////                webSocketServer.sendToAllClient(json);
//            }
//        }
    }

    /**
     * 查询工位一的倒数第四条记录（按创建时间倒序）
     */
    private Car getWorkPosition1Last4thCar() {
        LambdaQueryWrapper<Car> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Car::getWorkingPositionId, MessageConstant.workingPosition1)
                .orderByDesc(Car::getCreateTime)
                .last("LIMIT 2, 1"); // 倒数第四条（跳过前3条，取1条）
        return carMapper.selectOne(queryWrapper);
    }

    /**
     * 发送错误信息到WebSocket
     */
    private void sendErrorMessage() {
        try {
            Map<String, String> errorMap = new HashMap<>();
            errorMap.put("message", ERROR_MESSAGE);
            webSocketServer.sendToAllClient(JSON.toJSONString(errorMap));
        } catch (Exception e) {
            log.error("发送WebSocket错误信息失败", e);
        }
    }

    //螺丝超过8/2个时，就不操作数据库了，只是发信息给前端，提醒扭力多大
    @Async
    public void sendToAllClient(String gunNum,
                                Double extractTorque,TorqueStandards torqueStandards){
        Map map = new HashMap();
        if(torqueStandards == null){
            if(gunNum.equals("1")) {
                map.put("message", "··门铰链工位的车信息异常··");
                log.info("--未检测到车身工位信息-----");//extractFlag.equals("2") || ,extractFlag
//            map.put("alert", 2);//1 表示合格，0 2表示不合格
//                map.put("gunNum", gunNum);//哪枪测的数据
                map.put("torque", extractTorque); //扭力值是
                map.put("unit", MessageConstant.torqueUnit);
                String json = JSON.toJSONString(map);
                //log.info("json推消息:" + json);
                webSocketServer.sendToAllClient(json);//推消息
            }else if(gunNum.equals("2")){
                map.put("message", "··发动机盖工位的车信息异常··");
                log.info("--未检测到车头工位信息-----");//extractFlag.equals("2") || ,extractFlag
//            map.put("alert", 2);//1 表示合格，0 2表示不合格
//                map.put("gunNum",gunNum);//哪枪测的数据
                map.put("torque", extractTorque); //扭力值是
                map.put("unit", MessageConstant.torqueUnit);
                String json = JSON.toJSONString(map);
                //log.info("json推消息:"+json);
                webSocketServer.sendToAllClient(json);//推消息
            }else if(gunNum.equals("3")){
                //System.out.println("extractTorque为空");
                log.info("extractTorque为空");
                map.put("message", "··未检测到该工位的扭力标准信息··");
                String json = JSON.toJSONString(map);
                webSocketServer.sendToAllClient(json);
//                return;
            }else{
                map.put("message", "····未识别的枪号····");
                log.info("--未知名的枪-----");//extractFlag.equals("2") || ,extractFlag
//            map.put("alert", 2);//1 表示合格，0 2表示不合格
                map.put("gunNum",gunNum);//哪枪测的数据
                map.put("torque", extractTorque); //扭力值是
                map.put("unit", MessageConstant.torqueUnit);
                String json = JSON.toJSONString(map);
                //log.info("json推消息:"+json);
                webSocketServer.sendToAllClient(json);//推消息
            }
        }else {
            map.put("message", "达到拧紧次数，提示扭力····");
            if (extractTorque > torqueStandards.getMaximumTorque()) {
                log.info("--不合格-------扭力过大--------");//extractFlag.equals("2") || ,extractFlag
                map.put("alert", 2);//1 表示合格，0 2表示不合格
                map.put("gunNum", gunNum);//哪枪测的数据
                map.put("torque", extractTorque); //扭力值是
                map.put("unit", MessageConstant.torqueUnit);
                //把map转为json
                String json = JSON.toJSONString(map);
                //log.info("json推消息:" + json);
                webSocketServer.sendToAllClient(json);//推消息
            } else if (extractTorque < torqueStandards.getMinimumTorque()) {
                log.info("--不合格-------扭力过小--------");//extractFlag.equals("0") ||,extractFlag
                map.put("alert", 0);
                map.put("gunNum", gunNum);//哪枪测的数据
                map.put("torque", extractTorque);
                map.put("unit", MessageConstant.torqueUnit);
                //把map转为json
                String json = JSON.toJSONString(map);
                //log.info("json推消息:" + json);
                webSocketServer.sendToAllClient(json);//推消息
            } else if (extractTorque > torqueStandards.getMinimumTorque()
                    && extractTorque < torqueStandards.getMaximumTorque()
                    || extractTorque.equals(torqueStandards.getMaximumTorque())
                    || extractTorque.equals(torqueStandards.getMinimumTorque())) {
                log.info("--合格---------------");//extractFlag.equals("1") ||,extractFlag
                map.put("alert", 1);//1 表示合格，0 2表示不合格 Ng
                map.put("gunNum", gunNum);//哪枪测的数据
                map.put("torque", extractTorque); //扭力值是
                map.put("unit", MessageConstant.torqueUnit);
                //把map转为json
                String json = JSON.toJSONString(map);
                //log.info("json推消息:" + json);
                webSocketServer.sendToAllClient(json);//推消息
            }
        }
    }

    //当你在方法上添加 @Async 注解后，该方法将在单独的线程中异步执行。
    // 主线程不会被阻塞，因此可以继续执行后续代码
    // Spring 的异步处理依赖于动态代理，而动态代理只能拦截 public 方法的调用。
    //@Transactional 的基本作用就是保证方法内数据库操作的原子性（要么全做，要么全不做）。
    //Propagation.REQUIRES_NEW 在此基础上，强调了这个事务的独立性。它确保当前方法执行时，无论外部是否有事务，它都会启动一个不依赖于外部事务的新事务。
    // 它的成功或失败不会影响外部事务，反之亦然（外部事务的失败或提交也不会影响这个新事务）。
    @Async
    //@Transactional 自调用(实际上是目标对象内的方法调用目标对象的另一个方法)在运行时不会导致实际的事务
//    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void operationJDBC(Long workingPosition,screwType screwType, Car car, Screw screw,
                              String extractFlag, Double extractTorque,
                              TorqueStandards torqueStandards, String extractGunNum, int screwNum) {
        if(car.getId() == null){
            //System.out.println("车数据错误");
            log.info("车数据错误");
            Map map = new HashMap();
            map.put("message", "··工位"+workingPosition+"的车信息异常··");
            String json = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(json);
            return;
        }//get(0)
        if(screw.getCarId() == null){
            //System.out.println("螺丝数据错误");
            log.info("螺丝数据错误");
            Map map = new HashMap();
            map.put("message", "··"+extractGunNum+"号拧紧枪的螺丝信息异常··");
            String json = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(json);
            return;
        }
        if(extractTorque == null){
            //System.out.println("工位的扭力标准信息错误");
            log.info("工位的扭力标准信息错误");
            Map map = new HashMap();
            map.put("message", "··未检测到该工位的扭力标准信息··");
            String json = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(json);
            return;
        }
//---------------------------
        LambdaQueryWrapper<Screw> screwLambdaQueryWrapper = new LambdaQueryWrapper<>();
        screwLambdaQueryWrapper.eq(Screw::getCarId, screw.getCarId());
        screwLambdaQueryWrapper.eq(Screw::getScrewTypeId, screw.getScrewTypeId());
        Integer count = screwMapper.selectCount(screwLambdaQueryWrapper);
        log.info("screw是---"+screw);
        if(count == 0){
            screwService.save(screw);
            log.info("screw的主键是"+screw.getId());
        }else if(count == 1){
            screw = screwMapper.selectOne(screwLambdaQueryWrapper);
        }else {
            List<Screw> screwList = screwMapper.selectList(screwLambdaQueryWrapper);
            screw = screwList.get(0);
        }
//----------------------------
//        String gun1Num = gunProperties.getGun1();
//        String gun2Num = gunProperties.getGun2();
//        String gun3Num = gunProperties.getGun3();
//        String gun4Num = gunProperties.getGun4();
        //计算报警次数给到前端
        Object alarmsTime0 = CacheUtil.getFromCache("alarmsTime");
        int alarmsTime = 0;
        if(alarmsTime0 != null){
            alarmsTime = (int) alarmsTime0;
        }

        CarStatus carStatus = new CarStatus();
        carStatus.setCarId(car.getId());
        carStatus.setScrewId(screw.getId());
        carStatus.setScrewTypeId(screwType.getId());
        carStatus.setWorkingPositionId(workingPosition);
        String status = "";
        Map map = new HashMap();
        if(extractTorque > torqueStandards.getMaximumTorque()){
            log.info("不合格-------扭力过大--------{}",extractFlag);//extractFlag.equals("2") ||
            //计算报警次数给到前端
//            int alarmsTime = (int) CacheUtil.getFromCache("alarmsTime");
            alarmsTime = alarmsTime+1;
            CacheUtil.putInCache("alarmsTime",alarmsTime);
            log.info("扭力过大缓存是"+alarmsTime);
            carStatus.setAlarmLevel(CarStatus.AlarmLevel.danger);
            carStatus.setAlarmStatus(CarStatus.AlarmStatus.overTorque);
            carStatus.setCheckStatus(CarStatus.CheckStatus.waitForCheck);
            car.setAlarmCount(car.getAlarmCount()+1);//告警次数+1
            car.setPendingAlarmCount(car.getPendingAlarmCount()+1);//待处理;-'.;'
            //蜂鸣器响5秒
            jSerialCommIOService.buzzerControl();
            //检查有没有红灯缓存，如果没有就新建一个
            Object object = CacheUtil.getFromCache("redLight");
            if (object == null){
                List<Long> redLight = new ArrayList<>();
                redLight.add(screw.getId());
                CacheUtil.putInCache("redLight",redLight);
            }else {//如果有就加多一个
                //Object object = CacheUtil.getFromCache("redLight");
                List<Long> redLight = (List<Long>) object;//TODO 拧紧枪测试。。。
                redLight.add(screw.getId());
                CacheUtil.putInCache("redLight",redLight);
            }

            //绿灯灭
//            jSerialCommIOService.greenOut();
            //红灯亮
//            jSerialCommIOService.redUp();
            status = "2";
            map.put("alert", 2);//1 表示合格，0 2表示不合格
            map.put("alarmsTime",alarmsTime);
            map.put("screwType",screwType);
//            map.put("weldingGunId", extractNum); //哪把枪报的警
//            map.put("screwNum", screw.getScrewId()); //第几颗螺丝

            map.put("ScrewId", screw.getId()); //用于修改螺丝扭力，自生成的，唯一的
            map.put("workPositionId", workingPosition); //哪个工位报警
            map.put("torque", extractTorque); //扭力值是
            map.put("unit", MessageConstant.torqueUnit);
            //把map转为json
            String json = JSON.toJSONString(map);
            //log.info("json推消息:"+json);
            webSocketServer.sendToAllClient(json);//推消息
        } else if (extractTorque < torqueStandards.getMinimumTorque()) {
            log.info("不合格-------扭力过小--------{}",extractFlag);//extractFlag.equals("0") ||
//            int alarmsTime = (int) CacheUtil.getFromCache("alarmsTime");
            alarmsTime = alarmsTime+1;
            log.info("扭力过小缓存是"+alarmsTime);
            CacheUtil.putInCache("alarmsTime",alarmsTime);
            carStatus.setAlarmLevel(CarStatus.AlarmLevel.danger);
            carStatus.setAlarmStatus(CarStatus.AlarmStatus.underTorque);
            carStatus.setCheckStatus(CarStatus.CheckStatus.waitForCheck);
            car.setAlarmCount(car.getAlarmCount()+1);//告警次数+1
            car.setPendingAlarmCount(car.getPendingAlarmCount()+1);//待处理
            //蜂鸣器响5秒
            jSerialCommIOService.buzzerControl();
            //检查有没有红灯缓存，如果没有就新建一个
            Object object = CacheUtil.getFromCache("redLight");
            if (object == null){
                List<Long> redLight = new ArrayList<>();
                redLight.add(screw.getId());
                CacheUtil.putInCache("redLight",redLight);
            }else {//如果有就加多一个
                //Object object = CacheUtil.getFromCache("redLight");
                List<Long> redLight = (List<Long>) object;//TODO 拧紧枪测试。。。
                redLight.add(screw.getId());
                CacheUtil.putInCache("redLight",redLight);
            }
            //绿灯灭
//            jSerialCommIOService.greenOut();
            //红灯亮
//            jSerialCommIOService.redUp();
            status = "0";
            map.put("alert", 0);
            map.put("alarmsTime",alarmsTime);
            map.put("screwType",screwType);

//            map.put("weldingGunId", extractNum);
//            map.put("screwNum", screw.getScrewId()); //第几颗螺丝
            map.put("ScrewId", screw.getId()); //用于修改螺丝扭力
            map.put("workPositionId", workingPosition); //哪个工位报警
            map.put("torque", extractTorque);
            map.put("unit", MessageConstant.torqueUnit);
            //把map转为json
            String json = JSON.toJSONString(map);
            //log.info("json推消息:"+json);
            webSocketServer.sendToAllClient(json);//推消息
        } else if(extractTorque > torqueStandards.getMinimumTorque()
                && extractTorque < torqueStandards.getMaximumTorque()
                || extractTorque.equals(torqueStandards.getMaximumTorque())
                || extractTorque.equals(torqueStandards.getMinimumTorque())){
            log.info("合格---------------",extractFlag);//extractFlag.equals("1") ||
//            int alarmsTime = (int) CacheUtil.getFromCache("alarmsTime");

//            double result1 = (torqueStandards.getMaximumTorque() - torqueStandards.getMinimumTorque()) * 2.0 / 3.0;
//            double upperLimitAlertResult = torqueStandards.getMaximumTorque() - 2;
//            double lowerLimitAlertResult = torqueStandards.getMinimumTorque() + 2;
            double x = torqueStandards.getMaximumTorque() - torqueStandards.getMinimumTorque();
            double result2 = x * 0.9;
            double result3 = x * 0.1;
            //正常里的AlarmStatus分类
//            if(extractTorque > (result1+torqueStandards.getMinimumTorque())
//                    && extractTorque < torqueStandards.getMaximumTorque()) {//正常但是超过2/3
//                carStatus.setAlarmStatus(CarStatus.AlarmStatus.twoThirdsAlert);
//                carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);

//            if(extractTorque > upperLimitAlertResult
//                    && extractTorque < torqueStandards.getMaximumTorque()) {//正常但是超过2/3
//                carStatus.setAlarmStatus(CarStatus.AlarmStatus.upperLimitAlert);
//                carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);
//            }else if(extractTorque < lowerLimitAlertResult
//                    && extractTorque > torqueStandards.getMinimumTorque()){
//                carStatus.setAlarmStatus(CarStatus.AlarmStatus.lowerLimitAlert);
//                carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);
//            }else
            if(extractTorque > (result2+torqueStandards.getMinimumTorque())
                    && extractTorque < torqueStandards.getMaximumTorque()){
                carStatus.setAlarmStatus(CarStatus.AlarmStatus.alertUpperLimit);
                carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);
            } else if(extractTorque < (result3+torqueStandards.getMinimumTorque())
                    && extractTorque > torqueStandards.getMinimumTorque()) {
                carStatus.setAlarmStatus(CarStatus.AlarmStatus.alertLowerLimit);
                carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);
            }else {
                carStatus.setAlarmStatus(CarStatus.AlarmStatus.normal);
                carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);
            }

//            carStatus.setAlarmStatus(CarStatus.AlarmStatus.normal);
            carStatus.setAlarmLevel(CarStatus.AlarmLevel.normal);

//            carStatus.setCheckStatus(CarStatus.CheckStatus.Checked);
            status = "1";
            map.put("alert", 1);//1 表示合格，0 2表示不合格 Ng
            map.put("alarmsTime",alarmsTime);
            map.put("screwType",screwType);
//            map.put("weldingGunId", extractNum); //哪把枪报的警
//            map.put("screwNum", screw.getScrewId()); //第几颗螺丝
            map.put("ScrewId", screw.getId()); //用于修改螺丝扭力
            map.put("workPositionId", workingPosition); //哪个工位报警
            map.put("torque", extractTorque); //扭力值是
            map.put("unit", MessageConstant.torqueUnit);
            //把map转为json
            String json = JSON.toJSONString(map);
            //log.info("json推消息:"+json);
            webSocketServer.sendToAllClient(json);//推消息
        }
        carMapper.updateById(car);
        if(carStatus.getCheckStatus() == null){
            carStatus.setCheckStatus(CarStatus.CheckStatus.waitForCheck);
        }
        carStatus.setTorque(extractTorque);
        carStatus.setUnit(MessageConstant.torqueUnit);
        LambdaQueryWrapper<CarStatus> carStatusLambdaQueryWrapper = new LambdaQueryWrapper<>();
        carStatusLambdaQueryWrapper.eq(CarStatus::getCarId,car.getId());
        carStatusLambdaQueryWrapper.eq(CarStatus::getScrewTypeId,screw.getScrewTypeId());
        Integer count1 = carStatusMapper.selectCount(carStatusLambdaQueryWrapper);
        log.info("count1是--"+count1);
        if(count1 == 0){
            carStatusMapper.insert(carStatus);
        }
        //缓存主页螺丝数据
        ScrewIdAndTorqueCache homeCache = new ScrewIdAndTorqueCache();
        homeCache.setScrewTypeId(screwType.getId());
        homeCache.setScrewId(screw.getId());
        homeCache.setTorque(extractTorque);
        homeCache.setStatus(status);
        CacheUtil.putInCache("screw" + screwType.getId(), homeCache);
//        CacheUtil.putInCache("screw" + screwType.getId(), extractTorque);

        String gun1Num = gunProperties.getGun1();
        String gun2Num = gunProperties.getGun2();
        String gun3Num = gunProperties.getGun3();
        String gun4Num = gunProperties.getGun4();
        //获取
//        Object screwNumCache =
//        CacheUtil.getFromCache("screw" + screwType.getId());
//        log.info("screwNumCache是:"+screwNumCache);
        //将螺丝号存进缓存中，防止报错后需要重新计算
        if (extractGunNum.equals(gun1Num)) {
            CacheUtil.putInCache("screwNum51", screwNum);
            // Object screwNum51Cache = CacheUtil.getFromCache("screwNum51");
            // log.info("screwNumCache是" + screwNum51Cache);
        } else if (extractGunNum.equals(gun2Num)) {
            CacheUtil.putInCache("screwNum52", screwNum);
        } else if (extractGunNum.equals(gun3Num)) {
            CacheUtil.putInCache("screwNum53", screwNum);
        } else if (extractGunNum.equals(gun4Num)) {
            CacheUtil.putInCache("screwNum54", screwNum);
        } else {
            // 可选：处理未匹配的 extractGunNum
            log.info("未配对的枪: " + extractGunNum);
        }
    }

    public static String extractSubstring(String input, int startIndex, int endIndex) {
        // 检查输入字符串长度是否足够
        if (input.length() < endIndex) {
            throw new IllegalArgumentException("输入字符串长度不足，无法提取第 " + (startIndex + 1) + " 到 " + (endIndex) + " 位。");
        }
        // 使用 substring 方法提取子字符串
        return input.substring(startIndex, endIndex);
    }

}
